iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
JavaScript

用 TypeScript 重新定義前端開發:30 天的實踐與思考系列 第 26

Day26:使用 TypeScript 處理第三方庫中的型別定義

  • 分享至 

  • xImage
  •  

在開發前端應用時,我們經常需要使用第三方庫。然而,並不是所有的 JavaScript 第三方庫都自帶 TypeScript 的型別定義,所以我們需要瞭解如何為這些第三方庫添加或使用型別定義。這篇文章將介紹如何處理第三方庫中的型別定義,並提供簡單範例來展示如何正確地使用它們。

一、型別定義檔案是什麼?

TypeScript 型別定義檔案(Type Definition Files)是一種用來為 JavaScript 庫定義型別的檔案,即使在 JavaScript 庫中沒有原生的 TypeScript 支援,我們藉由這些特殊檔案依然可以享受型別檢查和編輯器的提示功能。

這些型別定義檔案通常以 .d.ts 為副檔名。

二、如何安裝型別定義

當你安裝一些常用的第三方庫時,這些庫通常自帶型別定義,比如 ReactLodash。但是有些庫可能沒有提供內建的型別支援。這時候,就可以從社群維護的 DefinitelyTyped 獲取型別定義。

你可以使用 npm 來安裝型別定義檔案,通常是在 @types 範圍包下找到對應的型別定義。例如:

npm install lodash @types/lodash --save

這樣就可以為 lodash 安裝對應的型別定義,並且不需要在項目中自己手動添加型別。

三、沒有型別定義的第三方庫

如果遇到使用的第三方庫沒有型別定義的情形,且又無法找到對應的 @types 定義包,可以有這幾種選擇:

  • 手動定義型別:自己為該庫創建型別定義檔案。
  • 使用 any:當不確定型別、或者該庫型別非常複雜時,可以暫時使用 any

1. 手動創建型別定義檔案

假設我們使用了一個名為 my-library 的 JavaScript 第三方庫,而這個庫沒有型別定義,我們就可以自己為它定義型別檔案。

(1) 第一步:在專案中創建一個 types 資料夾,然後在其中添加名為 my-library.d.ts 檔案。

// my-library.d.ts
declare module 'my-library' {
  export function hello(name: string): void;
}

(2) 第二步:可以在 TypeScript 中使用這個庫,並享受型別檢查和提示。

import { hello } from 'my-library';

hello('TypeScript'); // 正常工作
hello(123); // 編譯時會報錯,因為 hello 需要 string 參數

2. 使用 any

如果你暫時不想花太多時間去定義型別,可以用 any 來快速處理。any 可以暫時告訴 TypeScript 不對該庫進行型別檢查。

非必要情形,還是要盡量避免用 any 型別~

declare module 'my-library' {
  const myLibrary: any;
  export default myLibrary;
}

這樣,TypeScript 將暫時不會對 my-library 做詳細的型別檢查,可以在之後再撥時間回來定義具體的型別。

四、實際範例:處理沒有型別定義的第三方庫

現在假設我們使用了一個名為 date-fns 的第三方庫,但它沒有自帶型別定義。為了解決這個問題,可以透過安裝 @types/date-fns 來獲取型別定義。

首先,安裝 date-fns 和其對應的型別定義:

npm install date-fns @types/date-fns --save

安裝完成後,就可以在 TypeScript 檔案中享受型別提示和檢查:

import { format } from 'date-fns';

const formattedDate = format(new Date(), 'yyyy-MM-dd');
console.log(formattedDate);

在這裡,format 函式有完整的型別支援,TypeScript 會根據提供的參數自動檢查是否正確。

五、自動推斷與型別擴展

TypeScript 的一個強大功能是自動推斷第三方庫的型別。有些庫即使沒有明確的型別定義,TypeScript 也可以根據使用情境自動推斷型別。這在使用簡單的函式庫時非常方便。

另外,如果需要擴展第三方庫的功能,可以使用 TypeScript 的模組擴充功能來擴展庫的型別定義。這允許在不改變第三方庫原有代碼的情況下,為它添加額外的型別定義。

// 擴展 lodash 的型別
import _ from 'lodash';

declare module 'lodash' {
  interface LoDashStatic {
    customFunction(value: string): string;
  }
}

_.customFunction = function (value: string) {
  return `Hello, ${value}`;
};

console.log(_.customFunction('World'));  // Hello, World

在這個例子中,我們通過 declare module 擴展了 lodash 的型別定義,為它新增了一個 customFunction 方法。

六、總結

處理第三方庫的型別定義是 TypeScript 開發中經常遇到的挑戰之一。總結一下,有以下幾種方式可以使用與處理:

  • 使用內建型別定義:某些庫自帶型別定義,無需額外安裝。
  • 安裝社群維護的型別定義包:使用 @types 範圍的套件來為常見的庫添加型別支援。
  • 手動定義型別:當找不到型別定義時,可以自己撰寫簡單的 .d.ts 檔案。
  • 模組擴充與推斷型別:使用 TypeScript 的模組擴展功能來增強或擴展第三方庫的型別定義。

上一篇
Day25:TypeScript 的高級型別 (Advanced Types)
下一篇
Day27:使用 TypeScript 進行編譯階段錯誤檢查
系列文
用 TypeScript 重新定義前端開發:30 天的實踐與思考30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言